package com.symaster.common.connect.v3.socket;

import com.symaster.common.connect.v3.api.AcceptListener;
import com.symaster.common.util.IOUtil;

import java.io.Closeable;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author yinmiao
 * @version 2024/1/1
 */
public class TcpServer implements Closeable {

    private final Object treeLock = new Object();
    private final int port;
    private ServerSocket serverSocket;
    private boolean run = false;
    private AcceptListener acceptListener;

    public TcpServer(int port) {
        this.port = port;
    }

    public AcceptListener getAcceptListener() {
        return acceptListener;
    }

    public void setAcceptListener(AcceptListener acceptListener) {
        this.acceptListener = acceptListener;
    }

    public void start() {
        synchronized (treeLock) {
            if (run) {
                return;
            }
            run = true;
        }

        initServer();
        accept();
    }

    private void accept() {
        while (isRun()) {
            try {
                Socket accept = serverSocket.accept();
                if (acceptListener != null) {
                    acceptListener.accept(accept);
                }
            } catch (IOException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    public boolean isRun() {
        synchronized (treeLock) {
            return run;
        }
    }

    private void initServer() {
        try {
            serverSocket = new ServerSocket(port);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void close() throws IOException {
        synchronized (treeLock) {
            run = false;
        }
        IOUtil.close(serverSocket);
    }
}
